package graph.views;

import graph.algorithms.maxflow.FlowEdge;
import graph.algorithms.maxflow.FlowNetwork;
import graph.algorithms.maxflow.FordFulkerson;
import graph.drawings.GraphDrawing;
import graph.outils.io.GraphInput;
import graph.outils.io.GraphOutput;
import graph.views.DrawingForm.DrawingPanel;
import graph.views.RunningForm.RunningPanel;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class MainApp extends JFrame {

	private static DrawingPanel drawingPanel;
	private static RunningPanel runningPanel;
	private static JFrame mainFrame;
	

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event dispatch thread.
	 */
	private static void createAndShowGUI() {
		ToolbarPanel toolbarPanel = new ToolbarPanel();
		toolbarPanel.setToolbarAction(new ToobarAction());
		drawingPanel = new DrawingPanel();
		runningPanel = new RunningPanel();
		
		mainFrame = new JFrame();
		mainFrame.setJMenuBar(createMenuBar());
		mainFrame.getContentPane().add(toolbarPanel, BorderLayout.NORTH);
		
		mainFrame.getContentPane().add(runningPanel, BorderLayout.CENTER);
		mainFrame.getContentPane().add(drawingPanel, BorderLayout.CENTER);
		
		runningPanel.setVisible(false);
		drawingPanel.setVisible(true);

		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setExtendedState(MAXIMIZED_BOTH);
		mainFrame.pack();
		mainFrame.setVisible(true);
	}

	public static void main(String[] args) {
		// Schedule a job for the event dispatch thread:
		// creating and showing this application's GUI.
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				// Turn off metal's use of bold fonts
				UIManager.put("swing.boldMetal", Boolean.FALSE);
				createAndShowGUI();
			}
		});
	}

	private static JMenuBar createMenuBar() {
		JMenuBar menuBar = new JMenuBar();

		JMenu menu = new JMenu("File");
		menu.setMnemonic(KeyEvent.VK_F);
		menuBar.add(menu);

		JMenuItem productItem = new JMenuItem("New");
		productItem.setMnemonic(KeyEvent.VK_O);
		productItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,
				ActionEvent.ALT_MASK));
		productItem.setActionCommand("product");
		// productItem.addActionListener(this);
		menu.add(productItem);

		JMenuItem quitItem = new JMenuItem("Quit");
		quitItem.setMnemonic(KeyEvent.VK_Q);
		quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
				ActionEvent.ALT_MASK));
		quitItem.setActionCommand("quit");
		// quitItem.addActionListener(this);
		menu.add(quitItem);

		return menuBar;
	}

	enum Mode {
		Running, Drawing
	}

	private static Mode mode = Mode.Drawing;

	private static class ToobarAction implements IToolbarAction {

		@Override
		public void openAction() {
			JFileChooser fc = new JFileChooser();
			int returnVal = fc.showOpenDialog(mainFrame);

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fc.getSelectedFile();
				GraphDrawing graph = GraphInput.readXmlFile(file.getPath());
				drawingPanel.setGraphDrawing(graph);
			}
		}

		@Override
		public void newAction() {
			drawingPanel.setGraphDrawing(new GraphDrawing());
		}

		@Override
		public void saveAction() {
			JFileChooser fc = new JFileChooser();
			int returnVal = fc.showSaveDialog(mainFrame);

			if (returnVal == JFileChooser.APPROVE_OPTION) {
				File file = fc.getSelectedFile();
				GraphDrawing graphDrawing = drawingPanel.getGraphDrawing();
				GraphOutput.writeXmlFile(file.getPath(), graphDrawing);				
			}
			
			GraphDrawing graphDrawing = drawingPanel.getGraphDrawing();
			GraphOutput.writeXmlFile("test.xml", graphDrawing);
			System.out.println("saveAction");
		}

		@Override
		public void swichAction() {
//			if (mode == Mode.Drawing) {
//				mode = Mode.Running;
//				drawingPanel.setVisible(false);
//				runningPanel.setVisible(true);
//			} else {
//				mode = Mode.Drawing;
//				drawingPanel.setVisible(true);
//				runningPanel.setVisible(false);
//			}
//			
//			mainFrame.repaint();
//			System.out.println("swichAction");
//			
			int s = 0;
			int t = 3;
					
//			
			GraphDrawing graphDrawing = drawingPanel.getGraphDrawing();
			FlowNetwork flowNetwork = GraphInput.getFlowNetworkFrom(graphDrawing);
			//FordFulkersonAlgorithm maxflow = new FordFulkersonAlgorithm(flowNetwork, s, t);
			FordFulkerson maxflow = new FordFulkerson(flowNetwork, s, t);
			
			//maxflow.run();
//			flowNetwork = maxflow.getFlowNetwork();
//			GraphInput.UpdateGraphDrawingFrom(flowNetwork, graphDrawing);
//			drawingPanel.setGraphDrawing(graphDrawing);
			
			// compute maximum flow and minimum cut
			String result = "";
	        result += "Max flow from " + s + " to " + t + "\n";
	        for (int v = 0; v < flowNetwork.V(); v++) {
	            for (FlowEdge e : flowNetwork.adj(v)) {
	                if ((v == e.from()) && e.flow() > 0)
	                	result += "	" + e + "\n";
 	            }
	        }
//
//	        // print min-cut
	        System.out.print("Min cut: ");
//	        result += "\n\n Min cut: ";
	        for (int v = 0; v < flowNetwork.V(); v++) {
	            if (maxflow.inCut(v)) {
	            	result += v + "	";
	            }
	            	
	        }
	        System.out.println();
	        result += "\n " + "Max flow value = " +  maxflow.value();

	        System.out.println("Max flow value = " +  maxflow.value());
	        
	        drawingPanel.setResult(result);
		}

		@Override
		public void clearAciton() {
			System.out.println("clearAciton");
		}

	}
}
